#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <functional>
#include "Protocol.hpp"
using namespace std;

// 计算器业务处理
bool calProcess(const Request &req, Resopnse &resp)
{
    // 此时请求req已经反序列化完成，根据业务处理创建应答resp
    resp._exitcode = OK;
    resp._result = OK;

    switch (req._op)
    {
    case '+':
        resp._result = req._x + req._y;
        break;
    case '-':
        resp._result = req._x - req._y;
        break;
    case '*':
        resp._result = req._x * req._y;
        break;
    case '/':
    {
        if (req._y == 0)
            resp._exitcode = DIV_ZERO;
        else
            resp._result = req._x / req._y;
    }
    break;
    case '%':
    {
        if (req._y == 0)
            resp._exitcode = MOD_ZERO;
        else
            resp._result = req._x % req._y;
    }
    default:
        resp._exitcode = OP_ERR;
        break;
    }
    return false;
}

// 服务端 - 简单的计算器服务
void handlerEnter(const int &serversockfd)
{
    static std::string inbuffer; // 将多进程读入的数据写入到inbuffer中
    while (true)
    {
        // 1.读取数据
        // 1.1首先要保证我们读取的数据是一个完整的请求
        string req_text;
        if (!recvPackage(serversockfd, inbuffer, &req_text))
            return;
        LogMessage(NORMAL, "服务端读取的一个完整请求报文为:\n%s", req_text.c_str());

        // 1.2 这里保证了 读取的数据是一个完整的报文,此时需要删除报报文的头尾获取完整请求
        string req_str;
        if (!deLength(req_text, &req_str))
            return;
        LogMessage(NORMAL, "服务端去报头的完整请求为:\n%s", req_str.c_str());

        // 2.反序列化接收的字节流数据，得到一个结构化的请求对象Request
        Request req;
        if (!req.deserialize(req_str))
            return;

        // 3.根据请求Request进行业务处理，产生一个结构化的响应对象Respones   -- 这里是真正的业务处理
        Resopnse rsp;
        calProcess(req, rsp); // 根据req请 求，将结果写入到我们的回应rsp中

        // 4.将响应Respones序列化为字节流数据
        string rsp_str;
        rsp.serialize(&rsp_str);
        LogMessage(NORMAL, "服务端计算得出的序列化响应为:\n%s", rsp_str.c_str());
        LogMessage(NORMAL, "服务端计算得出的序列化响应长度为:\n%d", rsp_str.size());

        // 5.将序列化的响应发送回给客户端
        // 5.1 将序列化的响应response构建为完整的报文
        string send_string = enLength(rsp_str);
        LogMessage(NORMAL, "服务端发送的完整响应报文为:\n%s", send_string.c_str());

        send(serversockfd, send_string.c_str(), send_string.size(), 0); // 其实这里也是有问题的！
    }
}

class Task
{
    using func_t = std::function<void(int)>; // func是一个函数
public:
    Task() {}

    Task(int sock, func_t func)
        : _sock(sock), _callback(func) {}

    void operator()()
    {
        _callback(_sock);
        close(_sock); // 注意需要关闭文件描述符
    }

private:
    int _sock;
    func_t _callback; // 调用的函数
};